﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;

public class MyShoppingCart:DataTable
{
	public MyShoppingCart()
	{
        
        Columns.Add(new DataColumn("ProductId", Type.GetType("System.Int32")));
        Columns.Add(new DataColumn("Thumbnail", Type.GetType("System.String")));
        Columns.Add(new DataColumn("ProductName", Type.GetType("System.String")));
        Columns.Add(new DataColumn("UnitPrice", Type.GetType("System.Double")));
        Columns.Add(new DataColumn("Amount", Type.GetType("System.Int32")));
        Columns.Add(new DataColumn("Total", Type.GetType("System.Int32")));
        Columns.Add(new DataColumn("Remaining", Type.GetType("System.Int32")));
	    Constraints.Add("pkShoppingCart", Columns["ProductId"], true);
	    Columns[0].Caption = "Mã sản phẩm";
	    Columns[1].Caption = "Hình";
	    Columns[2].Caption = "Tên sách";
	    Columns[3].Caption = "Đơn giá";
	    Columns[4].Caption = "Số lượng";
	    Columns[5].Caption = "Tổng tiền";
	}

    private DataTable GetProductsTable(object Id)
    {
        return DataAccess.ExecuteQuery(
            "Select ProductId, Thumbnail, ProductName, Price, SaleOff, Amount from Products where ProductID =" + Id);
    }

    private float GetProductUnitPrice(DataTable dt)
    {
        if (dt.Rows.Count > 1)
            throw new Exception("The table has so many rows");
        float unitPrice = -1;
        if (dt.Rows.Count > 0 && dt.Rows[0]["Price"] != null)
        {
            bool b = float.TryParse(dt.Rows[0]["Price"].ToString(), out unitPrice);
            if(b && dt.Rows[0]["SaleOff"] != null)
            {
                float saleOff;
                b = float.TryParse(dt.Rows[0]["SaleOff"].ToString(), out saleOff);
                if(b)
                {
                    unitPrice -= saleOff;
                }
            }
            else
            {
                b = false;
            }
            return b ? unitPrice : -1;
        }
        return unitPrice;
    }

    public int GetProductAmount(DataTable dt)
    {
        if (dt.Rows.Count > 1)
            throw new Exception("The table has so many rows");
        int amount = -1;
        if (dt.Rows.Count > 0 && dt.Rows[0]["Amount"] != null)
        {
            bool b = int.TryParse(dt.Rows[0]["Amount"].ToString(), out amount);
            return b ? amount : -1;
        }
        return amount;
    }

    public bool AddItem(object Id, int _amount)
    {
        DataTable dt = GetProductsTable(Id);
        if(dt.Rows.Count == 0)
        {
            return false;
        }
        float unitPrice = GetProductUnitPrice(dt);
        int amount = GetProductAmount(dt);
        DataRow dr = Rows.Find(Id);
        if (dr == null)
        {
            if (amount > _amount)
                amount = _amount;
            dr = NewRow();
            dr["ProductID"]     = dt.Rows[0]["ProductID"];
            dr["Thumbnail"]     = dt.Rows[0]["Thumbnail"];
            dr["ProductName"]   = dt.Rows[0]["ProductName"];
            dr["UnitPrice"]     = unitPrice;
            dr["Amount"]        = amount;
            dr["Total"]         = amount * unitPrice;
            dr["Remaining"]     = dt.Rows[0]["Amount"];
            Rows.Add(dr);
        }
        else
        {
            _amount += int.Parse(dr["Amount"].ToString());
            if (amount > _amount)
                amount = _amount;
            
            unitPrice = float.Parse(dr["UnitPrice"].ToString());
            dr["Amount"] = amount;
            dr["Total"] = amount * unitPrice;
            dr["Remaining"] = dt.Rows[0]["Amount"];
        }
        return true;
    }

    public void JustifyAvailableProduct()
    {
        foreach (DataRow row in Rows)
        {
            DataTable dt = GetProductsTable(row["ProductID"]);
            int avaiAmount = GetProductAmount(dt);
            int amount = int.Parse(row["Amount"].ToString());
            if (avaiAmount <= 0)
                amount = 0;
            else if (avaiAmount < amount)
            {
                amount = avaiAmount;
            }
            row["Amount"] = amount;
            row["Remaining"] = avaiAmount;
        }
    }

    public bool UpdateAmount(int index, int newValue)
    {
        if (index >= Rows.Count || index < 0)
            return false;
        DataTable dt = GetProductsTable(Rows[index]["ProductID"]);
        int amount = GetProductAmount(dt);
        if(newValue > amount)
        {
            newValue = amount;
        }
        Rows[index]["Amount"] = newValue;
        return true;
    }

    public void UpdateOrder(SqlParameter[] _params)
    {
        int count = DataAccess.ExecuteProcNonQuery("SP_Orders_Insert", _params);
        if(count < 1)
            return;
        count = 0;
        foreach (DataRow row in Rows)
        {
            if(row["Amount"].Equals("0"))
            {
                ++count;
                continue;
            }
            _params = new[]{
                new SqlParameter("@ProductID", row["ProductID"]),
                new SqlParameter("@UnitPrice", row["UnitPrice"]), 
                new SqlParameter("@Amount", row["Amount"])
            };
            count = DataAccess.ExecuteProcNonQuery("SP_OrdersDetail_Insert", _params);
        }
        if (count == Rows.Count)
            DataAccess.ExecuteProcedure("SP_Orders_Delete");
        Rows.Clear();
    }

    public bool RemoveItem(object Id)
    {
        DataRow dr = Rows.Find(Id);
        if(dr != null)
        {
            Rows.Remove(dr);
            return true;
        }
        return false;
    }

    public bool RemoveItem(int index)
    {
        if (index >= Rows.Count)
            return false;
        Rows.RemoveAt(index);
        return true;
    }

    public void RemoveAll()
    {
        Rows.Clear();
    }

    public int TotalItems
    {
        get { return Rows.Count; }
    }

    public float TotalPrice
    {
        get
        {
            float total = 0;
            foreach (DataRow row in Rows)
            {
                total += float.Parse(row["Total"].ToString());
            }
            return total;
        }
    }
}
